package com.train.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.train.common.enums.impl.BizExceptionEnums;
import com.train.common.exception.GlobalException;
import com.train.common.resp.PageResp;
import com.train.system.bo.TrainCarriageBO;
import com.train.system.dto.carriage.TrainCarriageAddOrEditDTO;
import com.train.system.dto.carriage.TrainCarriageDTO;
import com.train.system.dto.carriage.TrainCarriagePageDTO;
import com.train.system.enums.impl.SeatColEnums;
import com.train.system.mapper.TrainCarriageMapper;
import com.train.system.po.TrainCarriagePO;
import com.train.system.resp.carriage.TrainCarriageDetailResp;
import com.train.system.resp.carriage.TrainCarriageListResp;
import com.train.system.resp.carriage.TrainCarriagePageResp;
import com.train.system.service.TrainCarriageService;
import com.train.system.service.TrainService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author baitiaojun
 * @description 针对表【trainCarriage(火车车厢)】的数据库操作Service实现
 * @createDate 2025-02-20 18:52:37
 */
@Service
@RequiredArgsConstructor
public class TrainCarriageServiceImpl extends ServiceImpl<TrainCarriageMapper, TrainCarriagePO>
    implements TrainCarriageService {

    private final TrainCarriageMapper trainCarriageMapper;

    @Lazy
    @Autowired
    private TrainService trainService;

    /**
     * 新增
     *  直接校验同车次是否存在该车厢
     * 更新
     *  同车次同一个车厢不校验车厢是否存在(id区别是否是同一个车厢)
     *  同车次不同车厢则校验车次是否存在
     *  同车次车厢不存在则不校验
     * @param trainCarriageAddOrEditDTO
     */
    @Override
    public void addOrEditTrainCarriage(TrainCarriageAddOrEditDTO trainCarriageAddOrEditDTO) {
        //校验车次是否存在
        trainService.validTrainCode(trainCarriageAddOrEditDTO.getTrainCode());

        //根据请求参数id判断是insert还是update
        if (trainCarriageAddOrEditDTO.getId() != null) {
            //如果是update,需要校验id记录是否存在
            if (!trainCarriageMapper.existsId(trainCarriageAddOrEditDTO.getId())) {
                throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CARRIAGE_NOT_EXISTS);
            }

            //查询同车次下不同车厢和箱号的映射关系
            List<TrainCarriageDTO> idCarriageList = trainCarriageMapper.getIdCodeList(trainCarriageAddOrEditDTO.getTrainCode());
            if (CollectionUtil.isEmpty(idCarriageList)) {
                throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CARRIAGE_NOT_EXISTS);
            }

            //过滤同车次下被更新的车厢, 仅收集同车次的车厢
            Map<Long, Integer> idCarriageMap
                    = idCarriageList.parallelStream()
                    .filter(item -> !item.getId().equals(trainCarriageAddOrEditDTO.getId()))
                    .collect(Collectors.toMap(TrainCarriageDTO::getId, TrainCarriageDTO::getIndex));

            //检查同车次中更被新车厢的箱号是否和其他箱号重合
            boolean exists = idCarriageMap.containsValue(trainCarriageAddOrEditDTO.getIndex());
            if (exists) {
                throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CARRIAGE_EXISTS);
            }
        } else {
            //查询同一车次的该车厢是否存在
            if (trainCarriageMapper.existsTrainCarriage(trainCarriageAddOrEditDTO.getTrainCode(), trainCarriageAddOrEditDTO.getIndex())) {
                throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CARRIAGE_EXISTS);
            }
        }

        //生成列数和座位数
        SeatColEnums[] seatColEnums = SeatColEnums.getByType(trainCarriageAddOrEditDTO.getSeatType());
        int colCount = seatColEnums.length;
        int seatCount = trainCarriageAddOrEditDTO.getRowCount() * colCount;

        TrainCarriagePO trainCarriagePO = BeanUtil.copyProperties(trainCarriageAddOrEditDTO, TrainCarriagePO.class);
        trainCarriagePO.setColCount(colCount);
        trainCarriagePO.setSeatCount(seatCount);
        boolean isSaved = this.saveOrUpdate(trainCarriagePO);
        if (!isSaved) {
            throw new GlobalException(BizExceptionEnums.EXP_ADD_TRAIN_CARRIAGE);
        }
    }

    @Override
    public PageResp<TrainCarriagePageResp> pageList(TrainCarriagePageDTO trainCarriagePageDTO) {
        return trainCarriageMapper.pageList(trainCarriagePageDTO);
    }

    @Override
    public void remove(Long id) {
        boolean isRemoved = this.removeById(id);
        if (!isRemoved) {
            throw new GlobalException(BizExceptionEnums.EXP_REMOVE_TRAIN_CARRIAGE);
        }
    }

    @Override
    public List<TrainCarriageBO> getTrainCarriageList(String trainCode) {
        List<TrainCarriageDTO> trainCarriageList = trainCarriageMapper.getTrainCarriageList(trainCode);
        if (CollectionUtil.isEmpty(trainCarriageList)) {
            throw new GlobalException(BizExceptionEnums.EXP_TRAIN_CARRIAGE_NOT_EXISTS);
        }
        return BeanUtil.copyToList(trainCarriageList, TrainCarriageBO.class);
    }

    @Override
    public TrainCarriageDetailResp getOne(TrainCarriageDTO trainCarriageDTO) {
        return trainCarriageMapper.getOne(trainCarriageDTO);
    }

    @Override
    public List<TrainCarriageListResp> getTrainCarriageListByTrainCodes(List<String> trainCodes) {
        return trainCarriageMapper.getTrainCarriageListByTrainCodes(trainCodes);
    }
}




